package model;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;

public final class WorldController {
    private static Hashtable<Integer, GameObject> gameObjects = new Hashtable<Integer, GameObject>();

    public static boolean solidObjectExists(int x, int y) {
        GameObject go = gameObjects.get(y + (x << 16));
        if (go != null && go.type() == 2 && go.x() == x && go.y() == y) {
            return true;
        }
        return false;
    }

    public static boolean canMove(int baseX, int baseY, int toX, int toY) {
        int diffX = baseX - toX;
        int diffY = baseY - toY;
        int moveX = 0;
        int moveY = 0;
        if (diffX < 0) {
            moveX = 1;
        } else if (diffX > 0) {
            moveX = -1;
        }
        if (diffY < 0) {
            moveY = 1;
        } else if (diffY > 0) {
            moveY = -1;
        }
        if (moveX > 0 && moveY > 0) {
            if (solidObjectExists(baseX + 1, baseY + 1) || solidObjectExists(baseX + 1, baseY) || solidObjectExists(baseX, baseY + 1)) {
                return false;
            }
        } else if (moveX < 0 && moveY < 0) {
            if (solidObjectExists(baseX - 1, baseY - 1) || solidObjectExists(baseX - 1, baseY) || solidObjectExists(baseX, baseY - 1)) {
                return false;
            }
        } else if (moveX > 0 && moveY < 0) {
            if (solidObjectExists(baseX + 1, baseY - 1) || solidObjectExists(baseX + 1, baseY) || solidObjectExists(baseX, baseY - 1)) {
                return false;
            }
        } else if (moveX < 0 && moveY > 0) {
            if (solidObjectExists(baseX - 1, baseY + 1) || solidObjectExists(baseX - 1, baseY) || solidObjectExists(baseX, baseY + 1)) {
                return false;
            }
        } else if (moveX < 0 && moveY == 0) {
            if (solidObjectExists(baseX - 1, baseY)) {
                return false;
            }
        } else if (moveX > 0 && moveY == 0) {
            if (solidObjectExists(baseX + 1, baseY)) {
                return false;
            }
        } else if (moveX == 0 && moveY < 0) {
            if (solidObjectExists(baseX, baseY - 1)) {
                return false;
            }
        } else if (moveX == 0 && moveY > 0) {
            if (solidObjectExists(baseX, baseY + 1)) {
                return false;
            }
        }
        return true;
    }

    public static void loadMap() {
        try {
            File[] files = new File("./cache/maps").listFiles();
            for (File f : files) {
                if (!f.getName().endsWith(".dat")) {
                    continue;
                }
                int regionId = Integer.parseInt(f.getName().replaceAll(".dat", ""));
                int baseX = (regionId >> 0x8) * 64;
                int baseY = (regionId & 0xff) * 64;
                DataInputStream in = new DataInputStream(new FileInputStream(f));
                int objectId;
                while ((objectId = in.readUnsignedShort()) != 65535) {
                    int xOffset;
                    while ((xOffset = in.readUnsignedByte()) != 255) {
                        int yOffset = in.readUnsignedByte();
                        int type = in.readUnsignedByte();
                        if (type != 0) {
                            gameObjects.put(baseY + yOffset + ((baseX + xOffset) << 16), new GameObject(objectId, type, baseX + xOffset, baseY + yOffset));
                        }
                    }
                }
                in.close();
            }
        } catch (IOException ioe) {
        }
    }
}